package com.servlet3.demo2.initializer;

import com.servlet3.demo2.config.MyMvcConfig;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

/**
 * 为什么tomcat启动的时候可以调用到我们实现的 WebApplicationInitializer 接口中的方法？
 *
 * 1、tomcat启动的时候会调用 javax.servlet.ServletContainerInitializer 接口的所有实现类的 onStartup 方法，对Servlet容器进行自定义的初始化。
 * 2、点开spring-web.jar包，在它的根目录下的/META-INF/services中有一个文件，
 *      文件名是 javax.servlet.ServletContainerInitializer，
 *      文件内容是 org.springframework.web.SpringServletContainerInitializer。
 *      根据servlet的规范(SPI机制)，tomcat启动的时候会加载里面的类（tomcat和spring都遵守这个规范）。
 * 3、SpringServletContainerInitializer 类实现了 ServletContainerInitializer 接口，因此会被实例化并调用它的 onStartup 方法。
 *      因为这个类上标注了 @HandlesTypes(WebApplicationInitializer.class) 注解，
 *      因此会向 onStartup 方法注入所有实现了 WebApplicationInitializer 接口的类作为方法入参。
 *      在 onStartup 方法中，会实例化 WebApplicationInitializer 类型的类，并对它们排序，依次调用它们的 onStartup 方法。
 */
public class WebInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        // 只使用SpringMVC容器
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(MyMvcConfig.class);
//        context.setServletContext(servletContext);
//        context.refresh();   // 可以不写

        DispatcherServlet dispatcherServlet = new DispatcherServlet(context);
        ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", dispatcherServlet);
        //映射路径
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
    }
}
